﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using HitachiLib.Utils;
using HitachiLib.Data;
using HitachiLib.HitachiServiceRef;

namespace HitachiApp.Model.Manage
{
    public class ManageViewModel : INotifyPropertyChanged
    {
        private Dictionary<int, Dictionary<int, ProjectResourceRelation>> project_resource_map;
        private ProjectBrowserModel project_browser;
        private ResourceBrowserModel resource_browser;
        private ProjectResourceRelationControlModel current_mapping;
        private Resource current_login;
        private MainPageModel main_page_model;

        public ManageViewModel(MainPageModel mpm)
        {
            project_browser = new ProjectBrowserModel(this);
            resource_browser = new ResourceBrowserModel(this);
            current_mapping = new ProjectResourceRelationControlModel(this);
            main_page_model = mpm;
        }

        public ProjectResourceRelationControlModel CurrentMapping
        {
            get { return current_mapping; }
        }
        public ResourceBrowserModel ResourceBrowserData
        {
            get { return resource_browser; }
        }

        public ProjectBrowserModel ProjectBrowserData
        {
            get { return project_browser; }
        }

        public void Update()
        {
            RaisePropertyChanged("CurrentMapping.ProjectRead.Access");
            RaisePropertyChanged("CurrentMapping.ProjectWrite.Access");
            RaisePropertyChanged("CurrentMapping.ResourceRead.Access");
            RaisePropertyChanged("CurrentMapping.ResourceWrite.Access");
            RaisePropertyChanged("CurrentMapping.ScheduleRead.Access");
            RaisePropertyChanged("CurrentMapping.ScheduleWrite.Access");
        }

        public void AddRelation(ProjectResourceRelation prr)
        {
            ProjectResourceData prd = prr.Data;
            if (!project_resource_map.ContainsKey(prd.ResourceID))
            {
                project_resource_map.Add(prd.ResourceID, new Dictionary<int, ProjectResourceRelation>());
            }
            Dictionary<int, ProjectResourceRelation> m = project_resource_map[prd.ResourceID];
            if (!m.ContainsKey(prd.ProjectID))
            {
                m.Add(prd.ProjectID, prr);
            }
        }

        public bool RemoveRelation(ProjectResourceData prd)
        {
            if (GetRelation(prd.ProjectID, prd.ResourceID) != null)
            {
                Dictionary<int, ProjectResourceRelation> res_map;
                if (project_resource_map.ContainsKey(prd.ResourceID))
                {
                    res_map = project_resource_map[prd.ResourceID];
                }
                else
                {
                    return false;
                }
                if (res_map.ContainsKey(prd.ProjectID))
                {
                    res_map.Remove(prd.ProjectID);
                }
                return true;
            }
            return false;
        }

        public bool AddRelation(ProjectResourceData prd)
        {
            if (GetRelation(prd.ProjectID, prd.ResourceID) == null)
            {
                Dictionary<int, ProjectResourceRelation> res_map;
                if (project_resource_map.ContainsKey(prd.ResourceID))
                {
                    res_map = project_resource_map[prd.ResourceID];
                }
                else
                {
                    res_map = new Dictionary<int,ProjectResourceRelation>();
                    project_resource_map.Add(prd.ResourceID, res_map);
                }
                ProjectResourceRelation prr = ProjectResourceRelation.GetUnique(prd);
                res_map.Add(prd.ProjectID, prr);
                return true;
            }
            return false;
        }

        public ProjectResourceRelation GetRelation(int project_id, int resource_id)
        {
            if (project_resource_map.ContainsKey(resource_id))
            {
                Dictionary<int, ProjectResourceRelation> res_map = project_resource_map[resource_id];
                if (res_map != null)
                {
                    if (res_map.ContainsKey(project_id))
                    {
                        ProjectResourceRelation prr = res_map[project_id];
                        if (prr != null)
                        {
                            return prr;
                        }
                    }
                }
            }
            return null;
        }

        public void RefreshCurrent()
        {
            if (resource_browser.CurrentSelected != null && project_browser.CurrentSelected != null)
            {
                current_mapping.Project = project_browser.CurrentSelected;
                current_mapping.Resource = resource_browser.CurrentSelected;
                ProjectResourceRelation prr = GetRelation(
                    project_browser.CurrentSelected.Data.Id,
                    resource_browser.CurrentSelected.Data.Id);
                current_mapping.Relation = prr;
                current_mapping.Refresh();
                RaisePropertyChanged("CurrentMapping");
            }
        }

        public void Load(Resource resource)
        {
            if (resource != null)
                current_login = resource;
            else
                resource = current_login;
            HitachiServiceClient client = WCFClient.GetClient();
            client.GetWholeManageDataByResourceIdCompleted +=
                new EventHandler<GetWholeManageDataByResourceIdCompletedEventArgs>(client_GetWholeManageDataByResourceIdCompleted);
            WCFClient.Retain();
            client.GetWholeManageDataByResourceIdAsync(resource.Data.ID);
        }

        private void client_GetWholeManageDataByResourceIdCompleted(object sender, GetWholeManageDataByResourceIdCompletedEventArgs e)
        {
            WCFClient.Release();
            WholeManageData data = e.Result;
            project_browser.Load(data.Projects);
            resource_browser.Load(data.Resources);
            project_resource_map = new Dictionary<int, Dictionary<int, ProjectResourceRelation>>();
            foreach (ProjectResourceData prd in data.ProjectResource)
            {
                if (!project_resource_map.ContainsKey(prd.ResourceID)) {
                    project_resource_map.Add(prd.ResourceID, new Dictionary<int,ProjectResourceRelation>());
                }
                Dictionary<int, ProjectResourceRelation> m = project_resource_map[prd.ResourceID];
                if (!m.ContainsKey(prd.ProjectID))
                {
                    ProjectResourceRelation prr = new ProjectResourceRelation(prd);
                    m.Add(prd.ProjectID, prr);
                }
            }
            RaisePropertyChanged("ProjectBrowserData");
            RaisePropertyChanged("ResourceBrowserData");
            main_page_model.ProjectTabViewModel.LoadWholeManageData(data);
            main_page_model.ResourceTabViewModel.LoadWholeManageData(data);
            main_page_model.ManageViewModel_Loaded = true;
        }

        #region PropertChanged Block
        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChanged(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }
        #endregion
    }
}
